/*
 * Copyright 2017 StreamSets Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.streamsets.datacollector.restapi;

import com.google.common.collect.ImmutableSet;
import com.streamsets.datacollector.activation.Activation;
import com.streamsets.datacollector.usagestats.StatsCollector;
import com.streamsets.datacollector.util.AuthzRole;
import com.streamsets.datacollector.util.PipelineException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Authorization;

import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

@Path("/v1/activation")
@Api(value = "activation")
@DenyAll
@RequiresCredentialsDeployed
public class ActivationResource {

  static final String LICENSE_TYPE = "licenseType";
  static final Set<String> AUTO_OPT_IN_TYPES = ImmutableSet.of("TRIAL", "REGISTRATION");

  private final Activation activation;
  private final StatsCollector statsCollector;

  @Inject
  public ActivationResource(Activation activation, StatsCollector statsCollector) {
    this.activation = activation;
    this.statsCollector = statsCollector;
  }

  @GET
  @ApiOperation(value = "Returns SDC activation information", response = Map.class, authorizations = @Authorization(value = "guest"))
  @Produces(MediaType.APPLICATION_JSON)
  @PermitAll
  public Response getActivation() throws PipelineException, IOException {
    return Response.status(Response.Status.OK).entity(activation).build();
  }

  @POST
  @ApiOperation(value = "Uploads the SDC activation key", response = Map.class, authorizations = @Authorization(value = "admin"))
  @Consumes(MediaType.TEXT_PLAIN)
  @Produces(MediaType.APPLICATION_JSON)
  @RolesAllowed({AuthzRole.ADMIN, AuthzRole.ADMIN_REMOTE, AuthzRole.ADMIN_ACTIVATION})
  public Response updateActivation(String activationKey) throws PipelineException, IOException {
    if (activation.isEnabled()) {
      activation.setActivationKey(activationKey);
      Map<String, Object> additionalInfo = Optional.ofNullable(activation.getInfo())
          .map(Activation.Info::getAdditionalInfo).orElse(Collections.emptyMap());
      Object licenseType = additionalInfo.get(LICENSE_TYPE);
      boolean canOptIn = licenseType == null || AUTO_OPT_IN_TYPES.contains(licenseType);
      if (!statsCollector.isOpted() && canOptIn) {
        statsCollector.setActive(true);
      }
      return Response.status(Response.Status.OK).entity(activation).build();
    } else {
      return Response.status(Response.Status.NOT_IMPLEMENTED).build();
    }
  }

}
